<template>
  <view class="chat-container">
    <!-- 公共组件-每个页面必须引入 -->
    <public-module></public-module>

    <!-- 头部 -->
    <view class="chat-header">
      <view class="title">AI助手</view>
      <view class="subtitle">我可以帮你搜索、答疑、写作，请把你的任务交给我吧~</view>
    </view>

    <!-- 聊天内容区域 -->
    <scroll-view
        class="chat-content"
        scroll-y
        :scroll-top="scrollTop"
        :scroll-with-animation="true"
        @scrolltoupper="loadMoreMessages"
        ref="chatScroll"
    >
      <!-- 欢迎消息 -->
      <view class="welcome-message" v-if="messages.length === 0">
        <u--image
            class="ai-avatar"
            width="120rpx"
            height="120rpx"
            :src="getImg('ai/ai_avatar.png')"
            mode="aspectFit"
        ></u--image>
        <view class="welcome-text">嗨！我是AI助手</view>
      </view>

      <!-- 消息列表 -->
      <view class="message-list">
        <view
            class="message-item"
            :class="item.role === 'user' ? 'user-message' : 'ai-message'"
            v-for="(item, index) in messages"
            :key="index"
        >
          <!-- 用户消息 -->
          <template v-if="item.role === 'user'">
            <view class="message-content user-content">
              <text>{{ item.content }}</text>
            </view>
            <view class="avatar-container">
              <u-avatar size="80rpx" :src="userInfo.headImage || userInfo.memberNumber"></u-avatar>
            </view>
          </template>

          <!-- AI消息 -->
          <template v-else>
            <view class="avatar-container">
              <u--image
                  class="ai-avatar"
                  width="80rpx"
                  height="80rpx"
                  :src="getImg('ai/ai_avatar.png')"
                  mode="aspectFit"
              ></u--image>
            </view>
            <view class="message-content ai-content">
              <view v-if="item.isLoading" class="typing-indicator">
                <view class="dot"></view>
                <view class="dot"></view>
                <view class="dot"></view>
              </view>
              <rich-text v-else :nodes="formatMessage(item.content)"></rich-text>
            </view>
          </template>
        </view>
      </view>
    </scroll-view>

    <!-- 底部输入区域 -->
    <view class="chat-footer">
      <view class="input-container">
        <u--textarea
            v-model="inputMessage"
            placeholder="请输入您的问题..."
            :autoHeight="true"
            :maxlength="-1"
            :confirmType="'send'"
            @confirm="sendMessage"
        ></u--textarea>
        <view class="action-buttons">
          <view class="action-item" @click="showFunctionPanel = !showFunctionPanel">
            <u-icon name="plus-circle" size="50rpx" color="#0E9C98"></u-icon>
          </view>
          <view class="action-item send-btn" @click="sendMessage">
            <u-icon name="arrow-upward" size="50rpx" color="#fff"></u-icon>
          </view>
        </view>
      </view>

      <!-- 功能面板 -->
      <view class="function-panel" v-if="showFunctionPanel">
        <view class="function-item" @click="useFunction('search')">
          <u--image
              width="80rpx"
              height="80rpx"
              :src="getImg('ai/search_icon.png')"
              mode="aspectFit"
          ></u--image>
          <text>联网搜索</text>
        </view>
        <view class="function-item" @click="useFunction('thinking')">
          <u--image
              width="80rpx"
              height="80rpx"
              :src="getImg('ai/thinking_icon.png')"
              mode="aspectFit"
          ></u--image>
          <text>深度思考</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
import {mapState} from "vuex";
import baseUrl from "@/config/baseUrl";
//import marked from 'marked';

export default {
  data() {
    return {
      socketTask: {},
      inputMessage: "",
      messages: [],
      isConnected: false,
      currentStreamingMessage: "",
      scrollTop: 0,
      showFunctionPanel: false,
      isStreaming: false,
      reconnectCount: 0,
      maxReconnectCount: 3,
      reconnectTimer: null
    };
  },
  computed: {
    ...mapState(["userInfo"]),
  },
  onLoad() {
    this.connectWebSocket();
  },
  onShow() {
    if (!this.isConnected) {
      // this.connectWebSocket();
    }
  },
  onUnload() {
    this.closeWebSocket();
  },
  onHide() {
    // 页面隐藏时不断开连接，保持会话
  },
  methods: {
    getImg(path) {
      return this.$base.ossUrl1 + path;
    },

    // WebSocket连接
    connectWebSocket() {
      try {
        const token = uni.getStorageSync('userToken') || this.userInfo.token || '';
        console.log(this.userInfo)
        // 先关闭之前的连接
        if (this.socket && this.isConnected) {
          this.closeWebSocket();
        }

        // 初始化心跳定时器
        if (this.heartbeatTimer) {
          clearInterval(this.heartbeatTimer);
          this.heartbeatTimer = null;
        }

        // 心跳间隔时间（毫秒）
        const HEARTBEAT_INTERVAL = 15000;

        // 先注册所有WebSocket事件监听器
        // 监听WebSocket连接打开事件
        uni.onSocketOpen((res) => {
          console.log('WebSocket已打开', res);
          this.isConnected = true;
          this.reconnectCount = 0; // 重置重连计数器

          this.heartbeatTimer = setInterval(() => {
            if (this.isConnected) {
               console.log(222222222)
              uni.sendSocketMessage({
                data: "ping",
                success: () => {
                  console.log('心跳发送成功');
                },
                fail: (error) => {
                  console.error('心跳发送失败:', error);
                  this.tryReconnect();
                }
              });
            }
          }, HEARTBEAT_INTERVAL);
        });

        // 监听WebSocket接收到服务器的消息事件
        uni.onSocketMessage((res) => {
          this.handleSocketMessage(res);
        });

        // 监听WebSocket错误事件
        uni.onSocketError((error) => {
          console.error('WebSocket错误:', error);
          uni.showToast({
            title: 'WebSocket连接错误',
            icon: 'none'
          });
          this.isConnected = false;
          this.tryReconnect();
        });

        // 监听WebSocket关闭事件
        uni.onSocketClose(() => {
          console.log('WebSocket已关闭');
          this.isConnected = false;
       //   this.tryReconnect();
        });

        // 创建WebSocket连接
        this.socketTask = uni.connectSocket({
          url: 'ws://192.168.10.78:8000/ws/'+this.userInfo.id+'?token='+token,
          header: {
            'userToken': `${token}`
          },
          success: (e) => {
            console.log('WebSocket连接创建成功');
            console.log(e)
            // 连接成功后启动心跳

          },
          fail: (error) => {
            console.error('WebSocket连接创建失败:', error);
            uni.showToast({
              title: 'WebSocket连接失败',
              icon: 'none'
            });
            this.isConnected = false;
          }
        });
      } catch (error) {
        console.error('WebSocket连接失败:', error);
        uni.showToast({
          title: 'WebSocket连接失败',
          icon: 'none'
        });
        this.isConnected = false;
      }
    },

    closeWebSocket() {
      // 清除心跳定时器
      if (this.heartbeatTimer) {
        clearInterval(this.heartbeatTimer);
        this.heartbeatTimer = null;
      }

      // 清除重连定时器
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
        this.reconnectTimer = null;
      }

      if (this.isConnected) {
        uni.closeSocket({
          success: () => {
            console.log('WebSocket关闭成功');
          },
          fail: (error) => {
            console.error('WebSocket关闭失败:', error);
          }
        });
        this.isConnected = false;
      }

      // 移除所有WebSocket事件监听
     /* uni.offSocketOpen();
      uni.offSocketMessage();
      uni.offSocketError();
      uni.offSocketClose();*/
    },

    // 处理WebSocket消息
    handleSocketMessage(res) {
       console.log(222222223)
       console.log(res)
      try {
        if(res.data==="pong"){
          return
        }
        const data = JSON.parse(res.data);

        // 处理流式输出
        if (data.type === 'stream') {
          // 如果是第一条流消息，添加一个AI消息
          if (!this.isStreaming) {
            this.isStreaming = true;
            this.messages.push({
              role: 'assistant',
              content: data.content,
              isLoading: false
            });
          } else {
            // 更新最后一条消息的内容
            const lastMessage = this.messages[this.messages.length - 1];
            lastMessage.content += data.content;
          }

          // 滚动到底部
          this.scrollToBottom();
        }
        // 处理流结束消息
        else if (data.type === 'end') {
          this.isStreaming = false;
        }
        // 处理普通消息
        else {
          this.messages.push({
            role: 'assistant',
            content: data.content,
            isLoading: false
          });
          this.scrollToBottom();
        }
      } catch (error) {
        console.error('解析WebSocket消息失败:', error);
      }
    },

    // 发送消息
    sendMessage() {
      if (!this.inputMessage.trim()) return;

      if (!this.isConnected) {
        uni.showToast({
          title: 'WebSocket未连接，正在重新连接...',
          icon: 'none'
        });
        this.connectWebSocket();
        return;
      }

      // 添加用户消息
      this.messages.push({
        type: "text",
        role: 'user',
        content: this.inputMessage,
        timestamp: Date.now()
      });

      // 添加AI正在输入的消息
      this.messages.push({
        role: 'assistant',
        content: '',
        isLoading: true
      });

      // 发送消息到WebSocket
      uni.sendSocketMessage({
        data: JSON.stringify({
          type: "text",
          content: this.inputMessage,
          timestamp: Date.now()
        }),
        success: () => {
          console.log('消息发送成功');
          // 清空输入框
          this.inputMessage = '';
          // 滚动到底部
          this.scrollToBottom();
        },
        fail: (error) => {
          console.error('消息发送失败:', error);
          uni.showToast({
            title: '消息发送失败',
            icon: 'none'
          });
          // 移除正在输入的消息
          this.messages.pop();
        }
      });
    },

    // 使用特定功能
    useFunction(type) {
      this.showFunctionPanel = false;

      let prefix = '';
      if (type === 'search') {
        prefix = '请帮我搜索：';
      } else if (type === 'thinking') {
        prefix = '请深入思考：';
      }

      this.inputMessage = prefix + this.inputMessage;
    },

    // 格式化消息内容（支持Markdown）
    formatMessage(content) {
      try {
        // 使用marked库将Markdown转换为HTML
        //  const html = marked(content);
        return content;
      } catch (error) {
        console.error('格式化消息失败:', error);
        return content;
      }
    },

    // 滚动到底部
    scrollToBottom() {
      this.$nextTick(() => {
        const query = uni.createSelectorQuery().in(this);
        query.select('.chat-content').boundingClientRect();
        query.exec((res) => {
          if (res && res[0]) {
            this.scrollTop = res[0].height * 100; // 乘以一个较大的数确保滚动到底部
          }
        });
      });
    },

    // 加载更多历史消息
    loadMoreMessages() {
      // 这里可以实现加载更多历史消息的逻辑
      console.log('加载更多历史消息');
    },
    // 尝试重新连接WebSocket
    tryReconnect() {
      // 清除之前的重连定时器
      if (this.reconnectTimer) {
        clearTimeout(this.reconnectTimer);
        this.reconnectTimer = null;
      }

      // 如果已经达到最大重连次数，则停止重连
      if (this.reconnectCount >= this.maxReconnectCount) {
        console.log(`已达到最大重连次数(${this.maxReconnectCount})，停止重连`);
        uni.showToast({
          title: 'WebSocket连接失败，请稍后再试',
          icon: 'none',
          duration: 2000
        });
        this.reconnectCount = 0;
        return;
      }

      // 递增重连计数
      this.reconnectCount++;

      // 使用指数退避策略，延迟重连
      const delay = Math.min(1000 * Math.pow(2, this.reconnectCount - 1), 10000);
      console.log(`${delay}ms后尝试第${this.reconnectCount}次重连...`);

      this.reconnectTimer = setTimeout(() => {
        console.log(`正在进行第${this.reconnectCount}次重连...`);
        this.connectWebSocket();
      }, delay);
    },
  }
}
</script>
<style lang="scss" scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f8f8f8;
}

.chat-header {
  padding: 40rpx 30rpx;
  /* #ifdef H5 */
  padding-top: 40rpx;
  /* #endif */
  /* #ifdef MP */
  padding-top: 140rpx;
  /* #endif */
  /* #ifdef APP-PLUS */
  padding-top: 100rpx;
  /* #endif */
  background: linear-gradient(to right, #eafffe, #f4f5f5);
  text-align: center;

  .title {
    font-size: 36rpx;
    font-weight: bold;
    color: #333;
    margin-bottom: 10rpx;
  }

  .subtitle {
    font-size: 28rpx;
    color: #666;
  }
}

.chat-content {
  flex: 1;
  padding: 20rpx;
  overflow-y: auto;

  .welcome-message {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 60rpx 0;

    .ai-avatar {
      margin-bottom: 30rpx;
    }

    .welcome-text {
      font-size: 32rpx;
      color: #333;
      font-weight: bold;
    }
  }

  .message-list {
    padding-bottom: 20rpx;
  }

  .message-item {
    display: flex;
    margin-bottom: 30rpx;

    &.user-message {
      flex-direction: row-reverse;
    }

    .avatar-container {
      width: 80rpx;
      height: 80rpx;
      flex-shrink: 0;
    }

    .message-content {
      max-width: 70%;
      padding: 20rpx;
      border-radius: 12rpx;
      margin: 0 20rpx;
      word-break: break-word;

      &.user-content {
        background-color: #0E9C98;
        color: #fff;
        border-top-right-radius: 0;
      }

      &.ai-content {
        background-color: #fff;
        color: #333;
        border-top-left-radius: 0;
        box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
      }
    }
  }
}

.chat-footer {
  padding: 20rpx;
  background-color: #fff;
  border-top: 1px solid #eee;

  .input-container {
    display: flex;
    align-items: flex-end;

    /deep/ .u-textarea {
      flex: 1;
      background-color: #f5f5f5;
      border-radius: 12rpx;
      padding: 20rpx;
      max-height: 200rpx;
      min-height: 80rpx;
    }

    .action-buttons {
      display: flex;
      margin-left: 20rpx;

      .action-item {
        width: 80rpx;
        height: 80rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-left: 10rpx;

        &.send-btn {
          background-color: #0E9C98;
          border-radius: 50%;
        }
      }
    }
  }
}

.function-panel {
  display: flex;
  padding: 30rpx 0;

  .function-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-right: 40rpx;

    text {
      font-size: 24rpx;
      color: #666;
      margin-top: 10rpx;
    }
  }
}


// 打字指示器动画
.typing-indicator {
  display: flex;
  align-items: center;

  .dot {
    width: 10rpx;
    height: 10rpx;
    border-radius: 50%;
    background-color: #999;
    margin: 0 5rpx;
    animation: typing 1.5s infinite ease-in-out;

    &:nth-child(1) {
      animation-delay: 0s;
    }

    &:nth-child(2) {
      animation-delay: 0.2s;
    }

    &:nth-child(3) {
      animation-delay: 0.4s;
    }
  }
}

@keyframes typing {
  0%, 60%, 100% {
    transform: translateY(0);
  }
  30% {
    transform: translateY(-10rpx);
  }
}

// Markdown样式
:deep(.ai-content) {
  line-height: 1.6;

  p {
    margin: 10rpx 0;
  }

  h1, h2, h3, h4, h5, h6 {
    margin: 20rpx 0 10rpx 0;
    font-weight: bold;
  }

  h1 {
    font-size: 36rpx;
  }

  h2 {
    font-size: 32rpx;
  }

  h3 {
    font-size: 30rpx;
  }

  ul, ol {
    padding-left: 40rpx;
    margin: 10rpx 0;
  }

  li {
    margin: 5rpx 0;
  }

  code {
    background-color: #f5f5f5;
    padding: 4rpx 8rpx;
    border-radius: 4rpx;
    font-family: monospace;
    font-size: 28rpx;
  }

  pre {
    background-color: #f5f5f5;
    padding: 20rpx;
    border-radius: 8rpx;
    overflow-x: auto;
    margin: 10rpx 0;

    code {
      background-color: transparent;
      padding: 0;
    }
  }

  blockquote {
    border-left: 4rpx solid #ddd;
    padding-left: 20rpx;
    color: #666;
    margin: 10rpx 0;
  }

  a {
    color: #0E9C98;
    text-decoration: none;
  }

  img {
    max-width: 100%;
    height: auto;
    margin: 10rpx 0;
    border-radius: 8rpx;
  }

  table {
    border-collapse: collapse;
    width: 100%;
    margin: 10rpx 0;

    th, td {
      border: 1px solid #ddd;
      padding: 10rpx;
      text-align: left;
    }

    th {
      background-color: #f5f5f5;
    }
  }
}
</style>
